嗯 API 所需要的參數內文雜湊 …
依照規格說明書的指示,需要以下的流程
(1) 先移除所有空值的參數,參數值前後不可有空白。
(2) 將剩餘所有參數值依照「參數名稱」由小至大排序。
(3) 如為多節點參數則不參與sign值演算
有點難懂 ?
直接看範例最快,就是把call API時的 JSON 由
{
"ShopNo": "BA0026_001",
"OrderNo": "A201804270001",
"Amount": 50000,
"CurrencyID": "TWD",
"PayType": "A",
"ATMParam": {"ExpireDate": "20180502"},
"CardParam": {},
"ConvStoreParam": {},
"PrdtName": "ThisDummyOrderNo",
"ReturnURL": "http://10.11.22.113:8803/QPay.ApiClient/Store/Return",
"BackendURL": "http://10.11.22.113:8803/QPay.ApiClient/AutoPush/PushSuccess",
}
轉換成如下的字串
'Amount=50000&BackendURL=http://10.11.22.113:8803/QPay.ApiClient/AutoPush/PushSuccess&CurrencyID=TWD&OrderNo=A201804270001&PayType=A&PrdtName=ThisDummyOrderNo&ReturnURL=http://10.11.22.113:8803/QPay.ApiClient/Store/Return&ShopNo=BA0026_001'
在此我們可以知道需要利用 Python 做到以下幾件事情
(1)移除不必要的參數,像是
"ATMParam": {"ExpireDate": "20180502"},
"CardParam": {},
"ConvStoreParam": {},
(2)送出去的參數需要先依 key 進行排序
雖然規格書中有提到此處的可以不用區分大小寫(例: a > B) ,但傳入參數前就全部依規格書使用首字大寫的參數最單純
# 等一下將 dict 格式轉成 json 時會利到
import json
# 將 api 所需要的參數直接以內建的 dict 方式讀入
send_message = {
"ShopNo": "BA0026_001",
"OrderNo": "A201804270001",
"Amount": 50000,
"CurrencyID": "TWD",
"PayType": "A",
"ATMParam": {"ExpireDate": "20180502"},
"CardParam": {},
"ConvStoreParam": {},
"PrdtName": "ThisDummyOrderNo",
"ReturnURL": "http://10.11.22.113:8803/QPay.ApiClient/Store/Return",
"BackendURL": "http://10.11.22.113:8803/QPay.ApiClient/AutoPush/PushSuccess",
}
# 檢查看看 CardParam 所對應的型別是?
print ( type(send_message["CardParam"]) )
## <class 'dict'>
## 由此我們可以知道,等一下要留下來不是 dict 的資料
## 說穿了就是要留下 str 與 int
## 不過為了簡化程式碼的邏輯,等一下就以 != dict 的方式來過濾資料
# 透過 Dictionary comprehension 一行就可以濾掉
send_message_filter = {
k: send_message[k] for k in send_message if type(send_message[k]) != dict
}
# 上述的程式碼與以下傳統的 for 迴圈是等價的
# 但就稍微冗長了點
send_message_filter = {}
for k in send_message:
if type(send_message[k]) != dict:
send_message_filter[k] = send_message[k]
# 將 key 進行排序,將此順序存到另外一個 list 中
sorted_key = sorted ( send_message_filter.keys() )
# 一樣透過 Dictionary comprehension 得到一個排序好的新 dict
send_message_orderby_key = {k: send_message_filter[k] for k in sorted_key}
# 將 dict 轉成 json (字串)
app_json = json.dumps(send_message_orderby_key)
# 印出來看看
print(app_json)
# {"Amount": 50000, "BackendURL": "http://10.11.22.113:8803/QPay.ApiClient/AutoPush/PushSuccess", "CurrencyID": "TWD", "OrderNo": "A201804270001", "PayType": "A", "PrdtName": "ThisDummyOrderNo", "ReturnURL": "http://10.11.22.113:8803/QPay.ApiClient/Store/Return", "ShopNo": "BA0026_001"}
# 透過內建的文字取代函數,就可以拿到最終的成果囉!
api_json.replace(": ", "=").replace(" ", "").replace(",", "&").replace('"', "").replace("{", "" ).replace("}", "")
今天主要是複習 comprehension 的用法與內建 json 函數。
嗯 第四天了,還在 api 參數的準備中 … 真的不是我故意的啊…